<template>
  <view
    class="wrapper"
    v-if="show"
    :style="[{ paddingTop: 'calc(' + statusBarHeight + 'px + 44px)' }]"
  >
    <topbar
      class="header"
      @cancel="cancel"
      @save="save"
      :labelConfirm="labelConfirm"
      :labelCancel="labelCancel"
    ></topbar>
    <view
      :style="'height:' + editorHeight + 'px;'"
      class="container"
      v-if="!previewMode && !showPreview"
    >
      <!--  #ifdef MP-ALIPAY -->
      <u-parse :html="html"></u-parse>
      <!--  #endif -->
      <!--  #ifndef  MP-ALIPAY -->
      <editor
        v-if="!previewMode && !showPreview"
        id="editor"
        class="ql-container"
        placeholder="开始输入..."
        showImgSize
        showImgToolbar
        showImgResize
        @statuschange="onStatusChange"
        :read-only="readOnly"
        @ready="onEditorReady"
      ></editor>
      <!--  #endif -->
    </view>
    <view
      class="toolbar"
      @tap="format"
      v-if="!showPreview"
      v-show="keyboardHeight || !autoHideToolbar"
      :style="'bottom:' + (isIOS ? keyboardHeight : 0) + 'px'"
    >
      <block v-for="(t, i) in getTools" :key="i">
        <view
          v-if="t == 'bold'"
          :class="formats.bold ? 'ql-active' : ''"
          class="iconfont icon-zitijiacu"
          data-name="bold"
          data-label="加粗"
        ></view>
        <view
          v-if="t == 'italic'"
          :class="formats.italic ? 'ql-active' : ''"
          class="iconfont icon-zitixieti"
          data-name="italic"
          data-label="斜体"
        ></view>
        <view
          v-if="t == 'underline'"
          :class="formats.underline ? 'ql-active' : ''"
          class="iconfont icon-zitixiahuaxian"
          data-name="underline"
          data-label="下滑线"
        ></view>
        <view
          v-if="t == 'strike'"
          :class="formats.strike ? 'ql-active' : ''"
          class="iconfont icon-zitishanchuxian"
          data-name="strike"
          data-label="删除线"
        ></view>
        <view
          v-if="t == 'align-left'"
          :class="formats.align === 'left' || !formats.align ? 'ql-active' : ''"
          class="iconfont icon-zuoduiqi"
          data-name="align"
          data-value="left"
          data-label="居左"
        ></view>
        <view
          v-if="t == 'align-center'"
          :class="formats.align === 'center' ? 'ql-active' : ''"
          class="iconfont icon-juzhongduiqi"
          data-name="align"
          data-value="center"
          data-label="居中"
        ></view>
        <view
          v-if="t == 'align-right'"
          :class="formats.align === 'right' ? 'ql-active' : ''"
          class="iconfont icon-youduiqi"
          data-name="align"
          data-value="right"
          data-label="居右"
        ></view>
        <view
          v-if="t == 'align-justify'"
          :class="formats.align === 'justify' ? 'ql-active' : ''"
          class="iconfont icon-zuoyouduiqi"
          data-name="align"
          data-value="justify"
          data-label="平铺"
        ></view>
        <!--                  <view :class="formats.lineHeight ? 'ql-active' : ''" class="iconfont icon-line-height" data-name="lineHeight"
                             data-value="2"></view>
                    <view :class="formats.letterSpacing ? 'ql-active' : ''" class="iconfont icon-Character-Spacing" data-name="letterSpacing"
                             data-value="2em"></view>
                    <view :class="formats.marginTop ? 'ql-active' : ''" class="iconfont icon-722bianjiqi_duanqianju" data-name="marginTop"
                             data-value="20px"></view>
                    <view :class="formats.previewarginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
                             data-name="marginBottom" data-value="20px"></view> -->
        <view
          v-if="t == 'remove'"
          class="iconfont icon-clearedformat"
          @tap.stop="removeFormat"
        ></view>
        <picker
          v-if="t == 'font'"
          class="iconfont"
          mode="selector"
          :range="fontSizeRange"
          @change="fontSize"
          ><view class="icon-fontsize"></view
        ></picker>
        <view
          v-if="t == 'color'"
          :style="fontColor != '#FFFFFF' ? 'color:' + formats.color : ''"
          class="iconfont icon-text_color"
          data-name="color"
          @tap.stop="openColor"
        ></view>
        <view
          v-if="t == 'backgroundColor'"
          :style="bgColor ? 'color:' + formats.backgroundColor : ''"
          class="iconfont icon-fontbgcolor"
          data-name="backgroundColor"
          @tap.stop="openColor"
        ></view>
        <view
          v-if="t == 'image'"
          class="iconfont icon-charutupian"
          @tap.stop="insertImage"
        ></view>
        <view
          v-if="t == 'clear'"
          class="iconfont icon-shanchu"
          @tap.stop="clear"
        ></view>
        <view
          v-if="t == 'preview'"
          class="iconfont icon-preview"
          @tap.stop="preview"
        ></view>
        <view
          v-if="t == 'date'"
          class="iconfont icon-date"
          @tap="insertDate"
        ></view>
        <view
          v-if="t == 'list-check'"
          class="iconfont icon-checklist"
          data-name="list"
          data-value="check"
        ></view>
        <view
          v-if="t == 'list-ordered'"
          :class="formats.list === 'ordered' ? 'ql-active' : ''"
          class="iconfont icon-youxupailie"
          data-name="list"
          data-value="ordered"
        ></view>
        <view
          v-if="t == 'list-bullet'"
          :class="formats.list === 'bullet' ? 'ql-active' : ''"
          class="iconfont icon-wuxupailie"
          data-name="list"
          data-value="bullet"
        ></view>
        <view v-if="t == 'undo'" class="iconfont icon-undo" @tap="undo"></view>
        <view v-if="t == 'redo'" class="iconfont icon-redo" @tap="redo"></view>
        <view
          v-if="t == 'outdent'"
          class="iconfont icon-outdent"
          data-name="indent"
          data-value="-1"
        ></view>
        <view
          v-if="t == 'indent'"
          class="iconfont icon-indent"
          data-name="indent"
          data-value="+1"
        ></view>
        <view
          v-if="t == 'divider'"
          class="iconfont icon-fengexian"
          @tap="insertDivider"
        ></view>
        <view
          v-if="t == 'h1'"
          :class="formats.header === 1 ? 'ql-active' : ''"
          class="iconfont icon-format-header-1"
          data-name="header"
          :data-value="1"
        ></view>
        <view
          v-if="t == 'h2'"
          :class="formats.header === 2 ? 'ql-active' : ''"
          class="iconfont icon-format-header-2"
          data-name="header"
          :data-value="2"
        ></view>
        <view
          v-if="t == 'h3'"
          :class="formats.header === 3 ? 'ql-active' : ''"
          class="iconfont icon-format-header-3"
          data-name="header"
          :data-value="3"
        ></view>
        <view
          v-if="t == 'h4'"
          :class="formats.header === 4 ? 'ql-active' : ''"
          class="iconfont icon-format-header-4"
          data-name="header"
          :data-value="4"
        ></view>
        <view
          v-if="t == 'h5'"
          :class="formats.header === 5 ? 'ql-active' : ''"
          class="iconfont icon-format-header-5"
          data-name="header"
          :data-value="5"
        ></view>
        <view
          v-if="t == 'h6'"
          :class="formats.header === 6 ? 'ql-active' : ''"
          class="iconfont icon-format-header-6"
          data-name="header"
          :data-value="6"
        ></view>
        <view
          v-if="t == 'sub'"
          :class="formats.script === 'sub' ? 'ql-active' : ''"
          class="iconfont icon-zitixiabiao"
          data-name="script"
          data-value="sub"
        ></view>
        <view
          v-if="t == 'super'"
          :class="formats.script === 'super' ? 'ql-active' : ''"
          class="iconfont icon-zitishangbiao"
          data-name="script"
          data-value="super"
        ></view>
        <view
          v-if="t == 'rtl'"
          :class="formats.direction === 'rtl' ? 'ql-active' : ''"
          class="iconfont icon-direction-rtl"
          data-name="direction"
          :data-value="formats.direction === 'rtl' ? '' : 'rtl'"
        ></view>
      </block>
    </view>
    <uni-popup ref="popup" type="bottom" @transed="colorPop">
      <colorPicker
        :color="color"
        :show="showColor"
        @confirm="colorChanged"
        @cancel="colorPopClose"
      ></colorPicker>
    </uni-popup>
    <view class="preview" v-show="showPreview"
      ><rich-text :nodes="htmlData" class="previewNodes"></rich-text
    ></view>
  </view>
</template>

<script>
import colorPicker from "../colorPicker.vue";
import uniPopup from "../uni-popup/uni-popup.vue";
import topbar from "./header.vue";
export default {
  components: {
    colorPicker,
    uniPopup,
    topbar
  },
  props: {
    show: {
      type: Boolean,
      default: false
    },

    value: {
      type: String
    },
    // imageUploader: {
    //   type: Function,
    // },
    muiltImage: {
      type: Boolean,
      default: false
    },
    compressImage: {
      type: Boolean,
      default: false
    },
    previewMode: {
      type: Boolean,
      default: false
    },
    autoHideToolbar: {
      type: Boolean,
      default: false
    },
    tools: {
      type: Array,
      default: function () {
        return [
          "bold",
          "italic",
          "underline",
          "strike",
          "align-left",
          "align-center",
          "align-right",
          "remove",
          "font",
          "color",
          "backgroundColor",
          "image",
          "clear",
          "preview"
        ];
      }
    }
  },
  data() {
    return {
      // show: true,
      readOnly: false,
      formats: {},
      fontColor: "#000000",
      bgColor: "",
      color: "",
      colorPickerName: "",
      showColor: false,
      fontSizeRange: [10, 12, 14, 16, 18, 24, 32],
      showPreview: false,
      htmlData: "",
      html: "",
      keyboardHeight: 0,
      editorHeight: 0,
      isIOS: false
    };
  },
  watch: {
    value: function (newvar) {
      this.html = newvar;
    },
    html: function (newvar) {
      if (this.previewMode) {
        this.previewData(this.html);
      }
      if (this.editorCtx) {
        this.editorCtx.setContents({
          html: this.html
        });
      }
    }
  },
  created() {
    this.html = this.value;
  },
  mounted: function () {
    const platform = uni.getSystemInfoSync().platform;
    this.isIOS = platform === "ios";
    if (this.previewMode) {
      this.previewData(this.html);
    }
    let keyboardHeight = 0;
    this.updatePosition(0);

    if (uni.onKeyboardHeightChange) {
      uni.onKeyboardHeightChange((res) => {
        if (res.height === keyboardHeight) return;
        const duration = res.height > 0 ? res.duration * 1000 : 0;
        keyboardHeight = res.height;
        setTimeout(() => {
          uni.pageScrollTo({
            scrollTop: 0,
            success: () => {
              this.updatePosition(keyboardHeight);
              this.editorCtx && this.editorCtx.scrollIntoView();
            }
          });
        }, duration);
      });
    }
  },
  computed: {
    getTools() {
      // #ifdef  MP-ALIPAY
      return ["image", "clear"];
      // #endif

      // #ifndef  MP-ALIPAY
      return this.tools;
      // #endif
    },

    labelConfirm: function () {
      return this.showPreview ? "关闭" : "保存";
    },
    labelCancel: function () {
      return this.showPreview ? "" : "取消";
    }
  },
  methods: {
    updatePosition(keyboardHeight) {
      const { windowHeight, windowWidth, platform } = uni.getSystemInfoSync();
      const rpx = windowWidth / 750;
      let topbarHeight = 85 * rpx;
      //#ifdef H5
      topbarHeight += 44;
      //#endif
      const toolbarHeight = (70 * Math.ceil(this.tools.length / 15) + 1) * rpx;

      const bodyHeight = windowHeight - topbarHeight;
      this.keyboardHeight = keyboardHeight;
      this.editorHeight =
        keyboardHeight > 0
          ? bodyHeight - keyboardHeight - toolbarHeight
          : this.autoHideToolbar
          ? bodyHeight
          : bodyHeight - toolbarHeight;
    },
    openColor(e) {
      var name = e.currentTarget.dataset.name;
      var color = this.formats[name];
      this.colorPickerName = name;
      if (name == "backgroundColor" && !color) {
        color = "#FFFFFF";
      }
      if (name == "color" && !color) {
        color = "#000000";
      }
      this.color = color;
      this.$refs.popup.open({
        type: "bottom"
      });
    },
    colorPop(e) {
      this.showColor = e.show;
    },
    colorPopClose() {
      this.$refs.popup.close();
    },
    colorChanged(e) {
      let label = "";
      switch (this.colorPickerName) {
        case "backgroundColor":
          if (e.color == "#FFFFFF") {
            e.color = "";
          }
          this.bgColor = e.color;
          label = "背景色";
          break;
        case "color":
          this.fontColor = e.color;
          label = "颜色";
          break;
      }
      this.colorPopClose();
      this._format(this.colorPickerName, e.color, label + e.color);
    },
    readOnlyChange() {
      this.readOnly = !this.readOnly;
    },
    onEditorReady() {
      uni
        .createSelectorQuery()
        .in(this)
        .select("#editor")
        .context((res) => {
          this.editorCtx = res.context;
          if (this.html) {
            this.editorCtx.setContents({
              html: this.html
            });
          }
        })
        .exec();
    },
    undo() {
      this.editorCtx.undo();
      this.toast("撤销");
    },
    redo() {
      this.editorCtx.redo();
      this.toast("重做");
    },
    format(e) {
      let { name, value, label } = e.target.dataset;
      if (!name) return;
      this._format(name, value, label);
    },
    _format(name, value, label) {
      this.editorCtx.format(name, value);
      this.toast(label);
    },
    toast(label) {
      uni.showToast({
        duration: 600,
        icon: "none",
        title: label
      });
    },
    onStatusChange(e) {
      const formats = e.detail;
      this.formats = formats;
    },
    insertDivider() {
      this.editorCtx.insertDivider({
        success: function () {
          this.toast("插入分割线");
        }
      });
    },
    clear() {
      // #ifndef  MP-ALIPAY
      this.editorCtx.clear({
        success: (res) => {
          this.toast("清空");
        }
      });
      // #endif
      // #ifdef  MP-ALIPAY
      this.html = "";
      // #endif
    },
    removeFormat() {
      this.editorCtx.removeFormat();
      this.toast("清除格式");
    },
    insertDate() {
      const date = new Date();
      const formatDate = `${date.getFullYear()}/${
        date.getMonth() + 1
      }/${date.getDate()}`;
      this.editorCtx.insertText({
        text: formatDate
      });
      this.toast("插入日期");
    },
    insertImage() {
      this.$utils.uploadImage(
        this.muiltImage ? 9 : 1,
        (res) => {
          // #ifndef  MP-ALIPAY
          this.editorCtx.insertImage({
            src: res,
            alt: "images"
          });
          // #endif
          // #ifdef  MP-ALIPAY
          this.html += `<img src="${res}"; style="width:100%;height:auto;" />`;
          // #endif
        },
        () => {},
        this.compressImage ? ["compressed"] : ["original"]
      );
    },
    fontSize(e) {
      const index = e.detail.value;
      const fz = this.fontSizeRange[index] + "px";
      this._format("fontSize", fz, "字体大小:" + fz);
    },
    cancel() {
      this.$emit("cancel");
    },
    save() {
      if (this.showPreview) {
        if (this.previewMode) {
          this.cancel();
        } else {
          this.showPreview = false;
        }
      } else {
        // #ifndef  MP-ALIPAY
        this.editorCtx.getContents({
          success: (res) => {
            // this.$emit("save", res);
            // this.$emit("input", res.html);
            this.Emit.$emit("editor", res.html);
          }
        });
        // #endif
        // #ifdef  MP-ALIPAY
        this.Emit.$emit("editor", this.html);
        // #endif
      }
    },
    previewData: function (html) {
      this.htmlData = html.replace(
        /\<img/gi,
        '<img style="max-width:100%;height:auto"'
      );
      this.showPreview = true;
    },
    preview: function () {
      this.editorCtx.getContents({
        success: (res) => {
          this.previewData(res.html);
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
@import "./editor-icon.css";

.wrapper {
  // padding: 5px;
  /* #ifdef H5 */
  padding-top: 0 !important;
  /* #endif */

  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  z-index: 1100;
  padding-bottom: calc(env(safe-area-inset-bottom) + 10rpx);

  .header {
    // width: 100%;
    // position: fixed;
    // z-index: 9;
    // left: 0;
    /* #ifndef H5 */
    // top: 0;
    /* #endif */
    /* #ifdef H5 */
    // top: 44px;
    /* #endif */
  }

  .container {
    flex: 1;
    height: 0 !important;
    width: 100%;
    // margin-top: 75rpx;
    background: #fff;

    .ql-container {
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      font-size: 16px;
      line-height: 1.5;
      overflow: auto;
      padding: 20rpx;
    }
  }

  .toolbar {
    display: flex;
    justify-content: space-around;
    // position: fixed;
    width: 100%;
    // left: 0;
    // bottom: 0;
    box-sizing: border-box;
    font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
    background-color: #fff;
    border-top: 1px solid #eee;
    line-height: 50rpx;

    .iconfont {
      display: inline-block;
      padding: 10rpx 0;
      width: 50rpx;
      text-align: center;
      font-size: 34rpx;
      box-sizing: border-box;
    }
  }
}

.preview {
  width: 100%;
  margin-top: 90rpx;

  .previewNodes {
    width: 100%;
    word-break: break-all;
  }
}

.ql-active {
  color: #06c;
}
</style>
